package com.esteel.settlement.config.pa;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;

import com.esteel.settlement.config.validator.PacketValidator;
import com.esteel.settlement.config.validator.ValidatorResult;
import com.esteel.settlement.pa.packet.Answer;
import com.esteel.settlement.pa.packet.BusinessHeader;
import com.esteel.settlement.pa.packet.PaPacket;
import com.esteel.settlement.pa.service.PacketProcesser;
import com.esteel.settlement.service.SettPacketLogService;

public class PaMessageProcessor /*implements BeanFactoryAware*/ {

	@Autowired
	private PacketValidator packetValidator;
	
	@Autowired
	private Map<String,ProcesserInfo> processer;
	
	@Autowired
	private BeanFactory beanFactory;
	
	@Autowired
	private SettPacketLogService settPacketLogService;
	
	private Logger logger =  LoggerFactory.getLogger(this.getClass());
	

	/**
	 * 执行 银行发出的接口的业务处理方法
	 * 
	 * @param packet
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public String execute(String packetStr) {

		logger.info(packetStr);
		
		Assert.isTrue(packetStr.length() > 344);

		try {
			// 读取报文信息
			byte[] src = packetStr.getBytes(Charset.forName("GBK"));
			byte[] bh = new byte[122];

			System.arraycopy(src, 222, bh, 0, bh.length);


//			// 读取业务头
			BusinessHeader buisinessHeader = new BusinessHeader();
			buisinessHeader.analyze(bh);

			String tranFunc = buisinessHeader.getTranFunc();

			Assert.notNull(tranFunc);
			ProcesserInfo info = processer.get(tranFunc);

			Assert.notNull(info);
			

			Object processer = this.beanFactory.getBean(info.getBeanName());

			
			Class<PacketProcesser<PaPacket, Answer>> cls = (Class<PacketProcesser<PaPacket, Answer>>) processer.getClass();

			PacketProcesser<PaPacket, Answer> proc = cls.cast(processer);
			
			Type type = info.getBeanClass().getGenericSuperclass();


			ParameterizedType pt = (ParameterizedType) type;
			Type[] args = pt.getActualTypeArguments();

			Class<PaPacket> clazz = (Class<PaPacket>) Class.forName(args[0].getTypeName());

			PaPacket packet = clazz.newInstance();
			packet.analyze(packetStr);
			
			//记录日志表
			settPacketLogService.add(packet);
			
			Answer answer = proc.execute(packet);
			
			//验证方法返回的结果是否正确
			ValidatorResult<Answer> result = packetValidator.validator(answer);
			Assert.isTrue(result.isValid(), result.getMessage());

			//记录日志
			settPacketLogService.add(answer);
			
			String answerStr = answer.marshal();
			
			logger.info(answerStr);
			
			return answerStr;



		} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {

			e.printStackTrace();
			return null;
		}

	}

}
